<template>
	<view class="beacon-container">
		<!-- 顶部状态栏 -->
		<view class="status-bar">
			<text class="status-text">蓝牙状态：{{bluetoothStatus}}</text>
			<text class="scan-status">{{autoScanStatus}}</text>
		</view>
		
		<!-- 签到开关 -->
		<view class="control-panel">
			<view class="switch-item">
				<text class="switch-label">自动签到</text>
				<switch :checked="autoSignEnabled" @change="toggleAutoSign" />
			</view>
			<view class="distance-setting">
				<text class="distance-label">签到距离：</text>
				<picker mode="selector" :value="signDistanceIndex" :range="signDistanceOptions" @change="changeSignDistance">
					<view class="distance-value">{{signDistanceOptions[signDistanceIndex]}}</view>
				</picker>
			</view>
			<view class="cooldown-setting">
				<text class="cooldown-label">冷却时间：</text>
				<picker mode="selector" :value="cooldownTimeIndex" :range="cooldownTimeOptions" @change="changeCooldownTime">
					<view class="cooldown-value">{{cooldownTimeOptions[cooldownTimeIndex]}}</view>
				</picker>
			</view>
		</view>
		
		<!-- 设备列表 -->
		<view class="device-list">
			<view class="list-title">检测到的设备：</view>
			<view v-if="detectedDevices.length === 0" class="no-device">
				暂未检测到设备
			</view>
			<view v-else class="device-item" v-for="(device, index) in detectedDevices" :key="index">
				<view class="device-info">
					<text class="device-name">{{device.name}}</text>
					<text class="device-rssi">信号强度: {{device.RSSI}}dBm</text>
					<text class="device-distance">距离: {{calculateDistance(device.RSSI).toFixed(3)}}m</text>
					<text class="device-time">最后检测: {{device.lastSeen}}</text>
				</view>
				<view class="sign-status" :class="device.signed ? 'signed' : 'unsigned'">
					{{device.signed ? '已签到' : '未签到'}}
				</view>
			</view>
		</view>
		
		<!-- 签到记录 -->
		<view class="sign-records">
			<view class="records-title">签到记录：</view>
			<view v-if="signRecords.length === 0" class="no-record">
				暂无签到记录
			</view>
			<view v-else class="record-item" v-for="(record, index) in signRecords" :key="index">
				<view class="record-info">
					<text class="record-device">设备名称：{{record.deviceName}}</text>
					<text class="record-id">设备ID：{{record.deviceId}}</text>
					<text class="record-time">签到时间：{{record.signTime}}</text>
					<text class="record-distance">签到距离：{{record.distance}}m</text>
				</view>
			</view>
			<button v-if="signRecords.length > 0" class="submit-btn" @click="submitSignRecords">
				提交签到记录
			</button>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				bluetoothStatus: '未初始化', // 蓝牙状态
				autoScanStatus: '未开始', // 自动扫描状态
				autoSignEnabled: false, // 自动签到开关
				detectedDevices: [], // 检测到的设备列表
				signRecords: [], // 签到记录
				scanTimer: null, // 扫描定时器
				signDistanceIndex: 0, // 签到距离选择索引
				signDistanceOptions: ['1米以内', '3米以内', '5米以内', '10米以内'], // 签到距离选项
				signDistanceValues: [1, 3, 5, 10], // 对应的距离值
				cooldownTimeIndex: 0, // 冷却时间选择索引
				cooldownTimeOptions: ['10秒', '30秒', '60秒', '120秒', '300秒', '600秒'], // 冷却时间选项
				cooldownTimeValues: [10, 30, 60, 120, 300, 600], // 对应的冷却时间值（秒）
				deviceSignCooldown: {}, // 设备签到冷却时间记录
			}
		},
		onLoad() {
			// 初始化蓝牙
			// this.initBluetooth()
		},
		onUnload() {
			// 页面卸载时停止扫描
			this.stopAutoScan()
		},
		methods: {
			// 初始化蓝牙
			async initBluetooth() {
				try {
					// 初始化蓝牙模块
					await uni.openBluetoothAdapter()
					
					// 监听蓝牙状态变化
					uni.onBluetoothAdapterStateChange((res) => {
						this.bluetoothStatus = res.available ? '可用' : '不可用'
						if (!res.available) {
							this.detectedDevices = []
							this.stopAutoScan()
						}
					})
					
					// 监听发现新设备
					uni.onBluetoothDeviceFound((res) => {
						console.log('发现设备:', res);
						
						const newDevices = res.devices
						// 过滤出名称包含"djk"的设备
						const djkDevices = newDevices.filter(device => {
							return device.name && device.name.includes('djk')
						})
						
						// 处理检测到的设备
						djkDevices.forEach(newDevice => {
							this.processDetectedDevice(newDevice)
						})
					})
					
					this.bluetoothStatus = '初始化成功'
					return Promise.resolve()
				} catch (error) {
					this.bluetoothStatus = '初始化失败：' + error.message
					uni.showToast({
						title: '蓝牙初始化失败',
						icon: 'none'
					})
					return Promise.reject(error)
				}
			},
			
			// 处理检测到的设备
			processDetectedDevice(newDevice) {
				const currentTime = this.formatTime(new Date())
				const distance = this.calculateDistance(newDevice.RSSI)
				
				// 查找设备是否已存在
				const existingIndex = this.detectedDevices.findIndex(device => device.deviceId === newDevice.deviceId)
				
				if (existingIndex === -1) {
					// 新设备，添加到列表
					const deviceInfo = {
						...newDevice,
						lastSeen: currentTime,
						signed: false,
						distance: distance
					}
					this.detectedDevices.push(deviceInfo)
				} else {
					// 更新现有设备信息
					this.detectedDevices[existingIndex] = {
						...this.detectedDevices[existingIndex],
						...newDevice,
						lastSeen: currentTime,
						distance: distance
					}
				}
				
				// 如果开启了自动签到，检查是否需要签到
				if (this.autoSignEnabled) {
					this.checkAutoSign(newDevice, distance)
				}
			},
			
			// 检查自动签到
			checkAutoSign(device, distance) {
				const signDistance = this.signDistanceValues[this.signDistanceIndex]
				const deviceId = device.deviceId
				const currentTime = Date.now()
				
				// 检查冷却时间（避免重复签到）
				const cooldownTime = this.cooldownTimeValues[this.cooldownTimeIndex] * 1000 // 转换为毫秒
				if (this.deviceSignCooldown[deviceId] && 
					currentTime - this.deviceSignCooldown[deviceId] < cooldownTime) {
					return
				}
				
				// 如果距离在签到范围内
				if (distance <= signDistance) {
					this.performSign(device, distance)
				}
			},
			
			// 执行签到
			performSign(device, distance) {
				const signTime = this.formatTime(new Date())
				
				// 添加签到记录
				const signRecord = {
					deviceName: device.name,
					deviceId: device.deviceId,
					signTime: signTime,
					distance: distance.toFixed(3)
				}
				this.signRecords.unshift(signRecord)
				
				// 更新设备签到状态
				const deviceIndex = this.detectedDevices.findIndex(d => d.deviceId === device.deviceId)
				if (deviceIndex !== -1) {
					this.detectedDevices[deviceIndex].signed = true
				}
				
				// 设置冷却时间
				this.deviceSignCooldown[device.deviceId] = Date.now()
				
				// 显示签到成功提示
				uni.showToast({
					title: `签到成功：${device.name}`,
					icon: 'success'
				})
				
				console.log('自动签到成功:', signRecord)
			},
			
			// 计算距离（根据RSSI估算）
			calculateDistance(rssi) {
				// 这是一个简单的距离估算公式，实际距离可能有偏差
				// RSSI转距离的经验公式
				const txPower = -59 // 1米处的RSSI值（需要根据实际设备调整）
				if (rssi === 0) return -1
				
				const ratio = rssi * 1.0 / txPower
				if (ratio < 1.0) {
					return Math.pow(ratio, 10)
				} else {
					const accuracy = (0.89976) * Math.pow(ratio, 7.7095) + 0.111
					return accuracy
				}
			},
			
			// 切换自动签到
			async toggleAutoSign(e) {
				const enabled = e.detail.value
				
				if (enabled) {
					// 开启自动签到前先检查蓝牙状态
					const bluetoothEnabled = await this.checkAndOpenBluetooth()
					if (bluetoothEnabled) {
						this.autoSignEnabled = true
						this.startAutoScan()
					} else {
						// 如果蓝牙未开启且用户拒绝开启，则不启用自动签到
						this.autoSignEnabled = false
					}
				} else {
					this.autoSignEnabled = false
					this.stopAutoScan()
				}
			},
			
			// 检查并打开蓝牙
			async checkAndOpenBluetooth() {
				return new Promise((resolve) => {
					// #ifdef APP-PLUS
					try {
						const BluetoothAdapter = plus.android.importClass('android.bluetooth.BluetoothAdapter')
						const blueadapter = BluetoothAdapter.getDefaultAdapter()
						
						if (blueadapter) {
							// 判断蓝牙是否开启
							if (blueadapter.isEnabled()) {
								// 已开启，重新初始化蓝牙
								uni.showToast({
									title: '蓝牙已打开',
									icon: 'success'
								})
								this.initBluetooth().then(() => {
									resolve(true)
								}).catch(() => {
									resolve(false)
								})
							} else {
								// 未开启弹出提示框
								uni.showModal({
									title: '提示',
									content: '蓝牙尚未打开，是否打开蓝牙？',
									showCancel: true,
									cancelText: '取消',
									confirmText: '确定',
									success: (res) => {
										if (res.confirm) {
											// 点击确定后通过系统打开蓝牙
											try {
												const result = blueadapter.enable()
												if (result) {
													uni.showToast({
														title: '正在打开蓝牙...',
														icon: 'loading'
													})
													// 等待蓝牙打开后再初始化
													this.waitForBluetoothAndInit(blueadapter).then((success) => {
														resolve(success)
													})
												} else {
													uni.showToast({
														title: '蓝牙打开失败',
														icon: 'error'
													})
													resolve(false)
												}
											} catch (error) {
												console.error('打开蓝牙失败:', error)
												uni.showToast({
													title: '蓝牙打开失败',
													icon: 'error'
												})
												resolve(false)
											}
										} else {
											// 点击取消
											console.log("用户取消打开蓝牙")
											resolve(false)
										}
									}
								})
							}
						} else {
							uni.showToast({
								title: '设备不支持蓝牙',
								icon: 'error'
							})
							resolve(false)
						}
					} catch (error) {
						console.error('蓝牙检查失败:', error)
						// 如果原生方法失败，回退到uni-app方法
						this.initBluetooth().then(() => {
							resolve(true)
						}).catch(() => {
							resolve(false)
						})
					}
					// #endif
					
					// #ifndef APP-PLUS
					// 非APP环境，直接初始化蓝牙
					this.initBluetooth().then(() => {
						resolve(true)
					}).catch(() => {
						resolve(false)
					})
					// #endif
				})
			},
			
			// 等待蓝牙打开并初始化
			async waitForBluetoothAndInit(blueadapter) {
				return new Promise((resolve) => {
					let checkCount = 0
					const maxChecks = 10 // 最多检查10次，避免无限循环
					
					const checkBluetooth = () => {
						checkCount++
						
						if (blueadapter.isEnabled()) {
							// 蓝牙已打开，初始化蓝牙
							uni.showToast({
								title: '蓝牙打开成功',
								icon: 'success'
							})
							this.initBluetooth().then(() => {
								resolve(true)
							}).catch(() => {
								resolve(false)
							})
						} else if (checkCount < maxChecks) {
							// 蓝牙还未打开，1秒后再次检查
							setTimeout(checkBluetooth, 1000)
						} else {
							// 超时，蓝牙仍未打开
							uni.showToast({
								title: '蓝牙打开超时',
								icon: 'error'
							})
							resolve(false)
						}
					}
					
					// 开始检查蓝牙状态
					checkBluetooth()
				})
			},
			
			// 开始自动扫描
			async startAutoScan() {
				try {
					this.autoScanStatus = '扫描中...'
					
					// 开始蓝牙设备扫描
					await uni.startBluetoothDevicesDiscovery({
						allowDuplicatesKey: true, // 允许重复上报同一设备
						interval: 2000 // 扫描间隔2秒
					})
					
					// 设置定时器，定期重新启动扫描以保持持续扫描
					this.scanTimer = setInterval(async () => {
						try {
							await uni.stopBluetoothDevicesDiscovery()
							await uni.startBluetoothDevicesDiscovery({
								allowDuplicatesKey: true,
								interval: 2000
							})
						} catch (error) {
							console.log('重新启动扫描失败:', error)
						}
					}, 30000) // 每30秒重新启动一次扫描
					
					this.autoScanStatus = '自动扫描中'
				} catch (error) {
					this.autoScanStatus = '扫描失败'
					uni.showToast({
						title: '启动扫描失败：' + error.message,
						icon: 'none'
					})
				}
			},
			
			// 停止自动扫描
			async stopAutoScan() {
				try {
					if (this.scanTimer) {
						clearInterval(this.scanTimer)
						this.scanTimer = null
					}
					
					await uni.stopBluetoothDevicesDiscovery()
					this.autoScanStatus = '已停止'
				} catch (error) {
					console.log('停止扫描失败:', error)
				}
			},
			
			// 改变签到距离
			changeSignDistance(e) {
				this.signDistanceIndex = e.detail.value
			},
			
			// 改变冷却时间
			changeCooldownTime(e) {
				this.cooldownTimeIndex = e.detail.value
			},
			
			// 格式化时间
			formatTime(date) {
				const year = date.getFullYear()
				const month = String(date.getMonth() + 1).padStart(2, '0')
				const day = String(date.getDate()).padStart(2, '0')
				const hours = String(date.getHours()).padStart(2, '0')
				const minutes = String(date.getMinutes()).padStart(2, '0')
				const seconds = String(date.getSeconds()).padStart(2, '0')
				
				return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
			},
			
			// 提交签到记录
			async submitSignRecords() {
				if (this.signRecords.length === 0) {
					uni.showToast({
						title: '暂无签到记录',
						icon: 'none'
					})
					return
				}
				
				try {
					// 显示确认对话框
					const res = await uni.showModal({
						title: '确认提交',
						content: `确定要提交${this.signRecords.length}条签到记录吗？提交后将清空记录并关闭自动签到。`,
						confirmText: '确定提交',
						cancelText: '取消'
					})
					
					if (res.confirm) {
						// 这里可以调用API提交数据到服务器
						// await this.uploadSignRecords(this.signRecords)
						
						console.log('提交签到记录:', this.signRecords)
						
						// 显示提交成功
						uni.showToast({
							title: '提交成功',
							icon: 'success'
						})
						
						// 清空签到记录
						this.signRecords = []
						
						// 关闭自动签到
						this.autoSignEnabled = false
						this.stopAutoScan()
						
						// 清空设备列表的签到状态
						this.detectedDevices.forEach(device => {
							device.signed = false
						})
						
						// 清空冷却时间记录
						this.deviceSignCooldown = {}
					}
				} catch (error) {
					uni.showToast({
						title: '提交失败：' + error.message,
						icon: 'none'
					})
				}
			}
		}
	}
</script>

<style>
.beacon-container {
	padding: 20rpx;
}

.status-bar {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 20rpx;
	background-color: #f8f8f8;
	border-radius: 10rpx;
	margin-bottom: 20rpx;
}

.status-text {
	font-size: 28rpx;
	color: #333;
}

.scan-status {
	font-size: 28rpx;
	color: #007AFF;
}

.control-panel {
	background-color: #fff;
	border-radius: 10rpx;
	padding: 20rpx;
	margin-bottom: 20rpx;
}

.switch-item {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-bottom: 20rpx;
}

.switch-label {
	font-size: 32rpx;
	color: #333;
}

.distance-setting {
	display: flex;
	justify-content: space-between;
	align-items: center;
}

.distance-label {
	font-size: 28rpx;
	color: #333;
}

.distance-value {
	font-size: 28rpx;
	color: #007AFF;
	padding: 10rpx;
	border: 1rpx solid #007AFF;
	border-radius: 10rpx;
}

.cooldown-setting {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin-top: 20rpx;
}

.cooldown-label {
	font-size: 28rpx;
	color: #333;
}

.cooldown-value {
	font-size: 28rpx;
	color: #ff9500;
	padding: 10rpx;
	border: 1rpx solid #ff9500;
	border-radius: 10rpx;
}

.device-list {
	background-color: #fff;
	border-radius: 10rpx;
	padding: 20rpx;
	margin-bottom: 20rpx;
}

.list-title {
	font-size: 32rpx;
	font-weight: bold;
	margin-bottom: 20rpx;
}

.no-device {
	text-align: center;
	color: #999;
	padding: 40rpx 0;
}

.device-item {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 20rpx;
	border-bottom: 1rpx solid #eee;
}

.device-info {
	flex: 1;
}

.device-name {
	font-size: 30rpx;
	color: #333;
	display: block;
	margin-bottom: 5rpx;
}

.device-rssi {
	font-size: 24rpx;
	color: #666;
	display: block;
	margin-bottom: 5rpx;
}

.device-distance {
	font-size: 24rpx;
	color: #007AFF;
	display: block;
	margin-bottom: 5rpx;
}

.device-time {
	font-size: 20rpx;
	color: #999;
	display: block;
}

.sign-status {
	font-size: 26rpx;
	padding: 5rpx 15rpx;
	border-radius: 15rpx;
}

.signed {
	background-color: #4cd964;
	color: #fff;
}

.unsigned {
	background-color: #ff9500;
	color: #fff;
}

.sign-records {
	background-color: #fff;
	border-radius: 10rpx;
	padding: 20rpx;
}

.records-title {
	font-size: 32rpx;
	font-weight: bold;
	margin-bottom: 20rpx;
}

.no-record {
	text-align: center;
	color: #999;
	padding: 40rpx 0;
}

.record-item {
	padding: 15rpx;
	background-color: #f8f8f8;
	border-radius: 10rpx;
	margin-bottom: 10rpx;
}

.record-info text {
	display: block;
	font-size: 26rpx;
	color: #333;
	margin-bottom: 5rpx;
}

.submit-btn {
	background-color: #007AFF;
	color: #fff;
	font-size: 30rpx;
	padding: 15rpx 40rpx;
	border-radius: 30rpx;
	margin-top: 20rpx;
	width: 100%;
}
</style>
